from django.http import HttpResponse
from rest_framework_jwt.views import ObtainJSONWebToken, RefreshJSONWebToken
from rest_framework.response import Response
from my_rest.serializers import MyJSONWebTokenSerializer,MyRefreshJSONWebTokenSerializer,ChangePasswordSerializer
from django.db import connection, transaction
from django.http import Http404
from django.core.exceptions import PermissionDenied
from rest_framework import exceptions
from rest_framework import status
from my_rest.exceptions import exception_detail
from my_rest.permissions import IsAuthenticated,IsSelf
import traceback
from rest_framework.views import APIView
import json

from core.tasks import user_tasks


def exception_handler(exc, context):
    """
    Returns the response that should be used for any given exception.

    By default we handle the REST framework `APIException`, and also
    Django's built-in `Http404` and `PermissionDenied` exceptions.

    Any unhandled exceptions may return `None`, which will cause a 500 error
    to be raised.
    """
    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()
    try:
        exc.detail = exception_detail.get(type(exc).__name__, exc.detail)  # 自定义错误消息，如果没有自定义，使用原生的
    except Exception:    # 捕获其他BUG导致的异常
        print(traceback.format_exc())
        return Response(data=traceback.format_exc(),status=500)

    if isinstance(exc, exceptions.APIException):
        headers = {}
        if getattr(exc, 'auth_header', None):
            headers['WWW-Authenticate'] = exc.auth_header
        if getattr(exc, 'wait', None):
            headers['Retry-After'] = '%d' % exc.wait

        if isinstance(exc.detail, (list, dict)):
            data = exc.detail
        else:
            data = {'detail': exc.detail}

        set_rollback()
        return Response(data, status=exc.status_code, headers=headers)
    return None


def set_rollback():
    atomic_requests = connection.settings_dict.get('ATOMIC_REQUESTS', False)
    if atomic_requests and connection.in_atomic_block:
        transaction.set_rollback(True)
        

class MyObtainJSONWebToken(ObtainJSONWebToken):
    """重构获取JWT"""
    serializer_class = MyJSONWebTokenSerializer


class MyRefreshJSONWebToken(RefreshJSONWebToken):
    """重构刷新Token"""
    serializer_class = MyRefreshJSONWebTokenSerializer


class ChangePassword(APIView):
    """修改用户密码， 需要带token
    PUT: \n
        Args:
            old_password: String, 旧密码(必须)
            password: String, 新密码(必须)
        Errors:
            status: 400,403,500
            non_field_errors: List, 常规错误，取第0个值
            detail: String， 系统内部错误以及权限错误
    """
    permission_classes = (IsAuthenticated,IsSelf)

    def get_object(self, pk,*fields):
        """获取原实例"""
        conditions = {'id':pk}
        task_res = json.loads(user_tasks.get_users(*fields,**conditions))
        try:
            return task_res['data'][0]
        except IndexError:
            raise Http404

    def put(self, request, pk, format=None):
        user_obj = self.get_object(pk)
        serializer = ChangePasswordSerializer(instance=user_obj, data=request.data)
        if serializer.is_valid():
            self.check_object_permissions(request, user_obj)
            serializer.save()
            return Response(dict(serializer.data))
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)




        # article = self.get_object(pk)
        # serializer = article_serializers.ArticleSerializer(instance=article,data=request.data)
        # if serializer.is_valid():
        #     self.check_object_permissions(request, article)    # 进行数据库操前，验证一下权限
        #     serializer.save(owner_id=1)
        #     return Response(dict(serializer.data))
        # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# class ChangePassword(APIView):
#     """修改用户密码"""
#
#     def post(self, request, format=None):
#
#         if serializer.is_valid():
#             serializer.save(operator_id=request.user['id'])    # 保存操作记录时，传入当前登陆的用户id
#             return Response(dict(serializer.data), status=201)
#
#         return Response(dict(serializer.errors), status=status.HTTP_400_BAD_REQUEST)




